using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;

namespace Pay.Core {
	/// <summary>
	/// 类型扩展方法类
	/// </summary>
	public static class TypeExtensions {
		/// <summary>
		/// 判断指定类型是否为数值类型
		/// </summary>
		/// <param name="type">要检查的类型</param>
		/// <returns>是否是数值类型</returns>
		public static bool IsNumeric(this Type type) {
			return type == typeof(Byte)
				|| type == typeof(Int16)
				|| type == typeof(Int32)
				|| type == typeof(Int64)
				|| type == typeof(SByte)
				|| type == typeof(UInt16)
				|| type == typeof(UInt32)
				|| type == typeof(UInt64)
				|| type == typeof(Decimal)
				|| type == typeof(Double)
				|| type == typeof(Single);
		}

		/// <summary>
		///  获取成员元数据的Description特性描述信息
		/// </summary>
		/// <param name="member">成员元数据对象</param>
		/// <param name="inherit">是否搜索成员的继承链以查找描述特性</param>
		/// <returns>返回Description特性描述信息，如不存在则返回成员的名称</returns>
		public static string ToDescription(this MemberInfo member, bool inherit = false) {
			DescriptionAttribute desc = member.GetAttribute<DescriptionAttribute>(inherit);
			return desc == null ? null : desc.Description;
		}

		/// <summary>
		/// 检查指定指定类型成员中是否存在指定的Attribute特性
		/// </summary>
		/// <typeparam name="T">要检查的Attribute特性类型</typeparam>
		/// <param name="memberInfo">要检查的类型成员</param>
		/// <param name="inherit">是否从继承中查找</param>
		/// <returns>是否存在</returns>
		public static bool AttributeExists<T>(this MemberInfo memberInfo, bool inherit) where T : Attribute {
			return memberInfo.GetCustomAttributes(typeof(T), inherit).Any(m => (m as T) != null);
		}

		/// <summary>
		/// 从类型成员获取指定Attribute特性
		/// </summary>
		/// <typeparam name="T">Attribute特性类型</typeparam>
		/// <param name="memberInfo">类型类型成员</param>
		/// <param name="inherit">是否从继承中查找</param>
		/// <returns>存在返回第一个，不存在返回null</returns>
		public static T GetAttribute<T>(this MemberInfo memberInfo, bool inherit) where T : Attribute {
			return memberInfo.GetCustomAttributes(typeof(T), inherit).SingleOrDefault() as T;
		}

		/// <summary>
		/// 从类型成员获取指定Attribute特性
		/// </summary>
		/// <typeparam name="T">Attribute特性类型</typeparam>
		/// <param name="memberInfo">类型类型成员</param>
		/// <param name="inherit">是否从继承中查找</param>
		/// <returns>存在返回第一个，不存在返回null</returns>
		public static T[] GetAttributes<T>(this MemberInfo memberInfo, bool inherit) where T : Attribute {
			return memberInfo.GetCustomAttributes(typeof(T), inherit).Cast<T>().ToArray();
		}

		public static Dictionary<string, object> ToDictionary(this Type type, Dictionary<string, string> dic_q) {
			var dic_q_q = new Dictionary<string, object>();
			var properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
			foreach (var propertie in properties) {
				if (dic_q.ContainsKey(propertie.Name)) {
					var q_val = dic_q[propertie.Name];
					object val = null;
					var propertie_type = propertie.PropertyType;
					if (propertie_type.IsEnum) {
						val = Enum.Parse(propertie_type, q_val);
					} else if (propertie_type == typeof(Guid)) {
						val = Guid.Parse(q_val);
					} else if (propertie_type.IsGenericType) {
						var argumentType = propertie_type.GetGenericArguments()[0];
						var genericType = propertie_type.GetGenericTypeDefinition();
						if (genericType == typeof(List<>))
							val = q_val.Split(',').Select(c => Convert.ChangeType(c, argumentType));
					} else {
						val = Convert.ChangeType(q_val, propertie_type);
					}
					dic_q_q.Add(propertie.Name, val);
				}
			}
			return dic_q_q;
		}
	}

}